﻿using AppDataStruct;
using ComClassLibrary;
using ComLib.ComFun;
using ComLib.ComType;
using ComLib.ConfigService;
using KWindow.KPageCore;
using LogLib;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Timers;
using System.Windows.Forms;

namespace YSLPages
{
    using HELOAMIMAGE = IntPtr;
    using HELOAMIMAGELIST = IntPtr;
    using HELOAMFTP = IntPtr;
    using HELOAMHTTP = IntPtr;
    using HELOAMDEVICE = IntPtr;
    using HELOAMVIDEO = IntPtr;
    using HELOAMVIEW = IntPtr;
    using HELOAMMEMORY = IntPtr;
    using HELOAMBASE64 = IntPtr;
    using HELOAMTHUMBNAIL = IntPtr;
    using HELOAMRECT = IntPtr;
    using HELOAMFONT = IntPtr;
    using HELOAMVIDEOCAP = IntPtr;
    using LPVOID = IntPtr;
    using LONG = Int32;
    using BOOL = Int32;
    using HWND = IntPtr;
    using COLORREF = UInt32;

    public partial class PageHighCapture : PageControlBase
    {

        #region Custom Controls
        private Button btnTakePhotoSFZZM;
        private Button btnTakePhotoSFZBM;
        private Button btnTakePhotoHKBHZY;
        private Button btnTakePhotoHKBBRY;
        private Button btnTakePhotoHKBBGY;
        private Button btnTakePhotoQTZJ;
        //private PictureBox pbxCapturedPhoto;
        private PictureBox pbxLiveView;
        private PictureBox pbxSFZZM;  //身份证正面
        private PictureBox pbxSFZBM;  //身份证背面
        private PictureBox pbxHKBHZY; //户口本户主页
        private PictureBox pbxHKBBRY; //户口本本人页
        private PictureBox pbxHKBBGY; //户口本变更页
        private PictureBox pbxQTZJ;   //其他证件
        #endregion

        //高拍句柄
        private HELOAMVIEW m_hView;
        //private HELOAMTHUMBNAIL m_hThumb;
        private HELOAMDEVICE m_hDev;
        private ELOAM_DEVCHANGECALLBACK DevChangeCallBack;
        private ELOAM_ATTACHCALLBAK attachCallback;
        //设别列表（专指视频）
        //List<HELOAMDEVICE> m_vDevice;
        HELOAMVIDEO m_hVideo;
        //HELOAMVIDEOCAP m_cap;
        //合成时的临时图片
        HELOAMIMAGE m_hImageTemp;
        private bool m_bIsInitDevice = false;
        private bool m_bIsInitVideo = false;
        private AppDirectory appDirs = new AppDirectory();
        //private ShareMemory shareMem = new ShareMemory(false);

        //private bool _bExit = false;
        //private byte[] _dataLiveView = new byte[ShareMemory.dataLength];
        //private static object _lockflag = new object();
        //private const string PhotoCapturer = "PhotoCapturer";
        //private const int MaxCount = 4;
        private PreApplyInfo _appInfo = null;
        private SFZInfo _sfzInfo = null;

        private YSLHighCaptureLTOption _option = new YSLHighCaptureLTOption();

        private Dictionary<string, string> _allPicPath = new Dictionary<string, string>();

        private bool HZChecked = false;
        private void InitDeviceControl()
        {
            try
            {
                _option.Load();
                if (null == pbxLiveView)
                {
                    MessageBox.Show("配置文件未配置pbxLiveView控件");
                    return;
                }

                Log.WriteAsync("当前工作路径1：" + Directory.GetCurrentDirectory());
                Log.WriteAsync("DLLl路径：" + EloamDll.GetDllPath());
                Log.WriteAsync("当前工作路径2：" + Directory.GetCurrentDirectory());

                m_hView = EloamDll.EloamGlobal_CreateView(pbxLiveView.Handle, IntPtr.Zero, 0);
                //m_hThumb = EloamDll.EloamGlobal_CreateThumbnail(pbxLiveView.Handle, IntPtr.Zero, 0);

                DevChangeCallBack =
                     new ELOAM_DEVCHANGECALLBACK(DEVCHANGECALLBACK);

                m_bIsInitDevice = false;
                if (1 != EloamDll.EloamGlobal_InitDevs(DevChangeCallBack, this.Handle))
                {
                    MessageBox.Show("初始化高拍仪失败！");
                    m_bIsInitDevice = true;
                    return;
                }

                m_bIsInitVideo = false;
                if (1 != EloamDll.EloamGlobal_VideoCapInit())
                {
                    MessageBox.Show("初始化视频录像失败！");
                }
                m_bIsInitVideo = true;
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
            }

        }

        private void ReleaseDeviceControl()
        {

            if (null != m_hView && m_hView != IntPtr.Zero)
            {
                var ret = EloamDll.EloamView_Release(m_hView);
            }
            if (null != m_hDev && m_hDev != IntPtr.Zero)
            {
                var ret = EloamDll.EloamDevice_Release(m_hDev);
            }
        }
        public uint RGB(uint r, uint g, uint b)
        {
            return (((b << 16) | (g << 8)) | r);
        }

        public void DEVCHANGECALLBACK(LONG type, LONG idx, LONG dbt, LPVOID userData)
        {
            if (1 != type)	// 只处理视频设备
                return;

            if (1 == dbt) // 设备到达
            {
                var hDev = EloamDll.EloamGlobal_CreateDevice(1, idx);

                //显示到界面
                IntPtr temp = EloamDll.EloamDevice_GetFriendlyName(hDev);
                string wName = Marshal.PtrToStringAuto(temp);

                //销毁字符串所占空间
                EloamDll.EloamGlobal_DestroyString(temp);

                if (_option.HighCaptureCameraName != wName)
                {
                    EloamDll.EloamDevice_Release(hDev);
                    return;
                }

                m_hDev = hDev;

                StartCapturer();

            }
            else if (2 == dbt) // 设备丢失
            {
                HELOAMDEVICE hDevTemp = EloamDll.EloamVideo_GetDevice(m_hVideo);
                CloseVideo();

                EloamDll.EloamDevice_Release(hDevTemp);
                EloamDll.EloamDevice_Release(m_hDev);
            }
        }

        public void ATTACHCALLBAK(HELOAMVIDEO video, LONG videoId, HELOAMVIEW view, LONG viewId, LPVOID userData)
        {
            //打开视频成功了
            if (null != btnTakePhotoSFZZM)
                btnTakePhotoSFZZM.Enabled = true;
            if (null != btnTakePhotoSFZBM)
                btnTakePhotoSFZBM.Enabled = true;
            if (null != btnTakePhotoHKBHZY)
                btnTakePhotoHKBHZY.Enabled = true;
            if (null != btnTakePhotoHKBBRY)
                btnTakePhotoHKBBRY.Enabled = true;
            if (null != btnTakePhotoHKBBGY)
                btnTakePhotoHKBBGY.Enabled = true;
            if (null != btnTakePhotoQTZJ)
                btnTakePhotoQTZJ.Enabled = true;
        }

        private void CloseVideo()
        {
            try
            {
                EloamDll.EloamView_SetText(m_hView, null, 0);
                EloamDll.EloamVideo_Release(m_hVideo);
                m_hVideo = IntPtr.Zero;

                EloamDll.EloamImage_Release(m_hImageTemp);
                m_hImageTemp = IntPtr.Zero;
                //EloamDll.EloamDevice_Release(m_hDev);
                if (m_bIsInitDevice)
                {
                    var ret = EloamDll.EloamGlobal_DeinitDevs();
                }
            }
            catch (Exception e)
            {
                Log.WriteException(e.ToString());
            }

        }

        /// <summary>
        /// 办理业务个人的材料翻拍照片保存路径
        /// </summary>
        private string _personalDirectory = "";
        private string PersonalDirectory
        {
            get
            {
                if (string.IsNullOrEmpty(_personalDirectory) && _appInfo != null)
                {
                    string passportID = _appInfo.SFZH + "_" + DateTime.Now.ToString("yyyyMMddHHmmss");
                    _personalDirectory = Path.Combine(appDirs.Materials, passportID);
                }

                if (string.IsNullOrEmpty(_personalDirectory))
                {
                    _personalDirectory = Path.Combine(appDirs.Materials, DateTime.Now.ToString("yyyyMMddHHmmss"));
                }

                if (!Directory.Exists(_personalDirectory))
                {
                    Directory.CreateDirectory(_personalDirectory);
                }
                return _personalDirectory;
            }
        }

        public PageHighCapture()
        {
            InitializeComponent();
            SetProcessBase(ProcessHightCapture.Instance);

        }

        /// <summary>
        /// 应用语言
        /// </summary>
        /// <param name="code"></param>
        public override void ApplyLanguage(string code)
        {
            base.ApplyLanguage(code);
        }

        private void GetControls()
        {
            btnTakePhotoSFZZM = GetControl<Button>("btnTakePhotoSFZZM") as Button;
            btnTakePhotoSFZBM = GetControl<Button>("btnTakePhotoSFZBM") as Button;
            btnTakePhotoHKBHZY = GetControl<Button>("btnTakePhotoHKBHZY") as Button;
            btnTakePhotoHKBBRY = GetControl<Button>("btnTakePhotoHKBBRY") as Button;
            btnTakePhotoHKBBGY = GetControl<Button>("btnTakePhotoHKBBGY") as Button;
            btnTakePhotoQTZJ = GetControl<Button>("btnTakePhotoQTZJ") as Button;

            pbxLiveView = GetControl<PictureBox>("pbxLiveView") as PictureBox;

            pbxSFZZM = GetControl<PictureBox>("pbxSFZZM") as PictureBox;
            pbxSFZBM = GetControl<PictureBox>("pbxSFZBM") as PictureBox;
            pbxHKBHZY = GetControl<PictureBox>("pbxHKBHZY") as PictureBox;
            pbxHKBBRY = GetControl<PictureBox>("pbxHKBBRY") as PictureBox;
            pbxHKBBGY = GetControl<PictureBox>("pbxHKBBGY") as PictureBox;
            pbxQTZJ = GetControl<PictureBox>("pbxQTZJ") as PictureBox;
        }

        public override void InitCtrls()
        {
            base.InitCtrls();
            GetControls();
            //pbxLiveView.SizeMode = PictureBoxSizeMode.Zoom;
            //pbxCapturedPhoto.SizeMode = PictureBoxSizeMode.Zoom;
            //pbxCapturedPhoto.BackgroundImageLayout = ImageLayout.Zoom;
            pbxSFZZM.BackgroundImageLayout = ImageLayout.Zoom;
            pbxSFZBM.BackgroundImageLayout = ImageLayout.Zoom;
            pbxHKBHZY.BackgroundImageLayout = ImageLayout.Zoom;
            pbxHKBBRY.BackgroundImageLayout = ImageLayout.Zoom;
            pbxHKBBGY.BackgroundImageLayout = ImageLayout.Zoom;
            pbxQTZJ.BackgroundImageLayout = ImageLayout.Zoom;

            SetButtonDefaultStyles(btnTakePhotoSFZZM);
            SetButtonDefaultStyles(btnTakePhotoSFZBM);
            SetButtonDefaultStyles(btnTakePhotoHKBHZY);
            SetButtonDefaultStyles(btnTakePhotoHKBBRY);
            SetButtonDefaultStyles(btnTakePhotoHKBBGY);
            SetButtonDefaultStyles(btnTakePhotoQTZJ);

            SetButtonDefaultStyles(buttonCancel);
            SetButtonDefaultStyles(buttonBack);
            SetButtonDefaultStyles(buttonNext);

            if (null != btnTakePhotoSFZZM)
                btnTakePhotoSFZZM.Enabled = false;
            if (null != btnTakePhotoSFZBM)
                btnTakePhotoSFZBM.Enabled = false;
            if (null != btnTakePhotoHKBHZY)
                btnTakePhotoHKBHZY.Enabled = false;
            if (null != btnTakePhotoHKBBRY)
                btnTakePhotoHKBBRY.Enabled = false;
            if (null != btnTakePhotoHKBBGY)
                btnTakePhotoHKBBGY.Enabled = false;
            if (null != btnTakePhotoQTZJ)
                btnTakePhotoQTZJ.Enabled = false;
        }

        private void PageCopyingPhotography_Load(object sender, EventArgs e)
        {
            Log.WriteAsync("====================[" + this.Name + "Start]====================");
        }

        //初始化窗体数据
        public override void InitData()
        {
            base.InitData();
            try
            {
                _appInfo = Process.GetValue<PreApplyInfo>("PreApplyInfo");
                _sfzInfo = Process.GetValue<SFZInfo>("SFZInfo");

                if (Process.ContainsKey("HZChecked"))
                {
                    HZChecked = Process.GetValue<bool>("HZChecked");
                }
                else
                {
                    HZChecked = false;
                }

                _personalDirectory = "";
                _allPicPath.Clear();
                SetPictureBoxEmpty();

                IDCardAll cardInfo = Process.GetValue<IDCardAll>("IDCardInfo");
                if (null != cardInfo)
                {
                    using (FileStream stream = new FileStream(cardInfo.FrontImage, FileMode.Open, FileAccess.Read))
                    {
                        _appInfo.SFZZM = cardInfo.FrontImage;
                        _sfzInfo.SFZZM= cardInfo.FrontImage;
                        pbxSFZZM.BackgroundImage = Image.FromStream(stream);
                    }

                    using (FileStream stream = new FileStream(cardInfo.BackImage, FileMode.Open, FileAccess.Read))
                    {
                        _appInfo.SFZBM = cardInfo.BackImage;
                        _sfzInfo.SFZBM = cardInfo.BackImage;
                        pbxSFZBM.BackgroundImage = Image.FromStream(stream);
                    }

                    _allPicPath.Add((string)btnTakePhotoSFZZM.Tag, cardInfo.FrontImage);
                    _allPicPath.Add((string)btnTakePhotoSFZBM.Tag, cardInfo.BackImage);
                }
                //UpdatePicture(pbxCapturedPhoto,"");
            }
            catch (Exception ex)
            {
                Log.WriteAsync(ex.Message);
                Log.WriteException(ex.ToString());
            }
        }

        public override void StartWork()
        {
            base.StartWork();
            //InitDeviceControl();
            if (IsMainPage)
            {
                if (m_hDev == IntPtr.Zero)
                    InitDeviceControl();
                else
                    StartCapturer();
            }

            //Speak("请摘下口罩，并目视前方摄像头，点击拍照按钮，完成现场人像采集后，点击下一步按钮");
        }

        public override void StopWork()
        {
            base.StopWork();
            //_motion.TurnOffLight(LEDS.PaperPrinter);
            if (IsMainPage)
            {
                StopCapturer();
            }
        }

        private void StartCapturer()
        {
            //打开视频
            EloamDll.EloamVideo_Release(m_hVideo);

            m_hVideo = EloamDll.EloamDevice_CreateVideo(
                m_hDev, 1, 1, null, (IntPtr)0, null, (IntPtr)0, 0, 2);

            if (null != m_hVideo && m_hVideo != IntPtr.Zero)
            {
                attachCallback = new ELOAM_ATTACHCALLBAK(ATTACHCALLBAK);
                EloamDll.EloamView_SelectVideo(m_hView, m_hVideo, attachCallback, this.Handle);
                EloamDll.EloamView_SetText(m_hView, "打开视频中，请等待...", RGB(255, 255, 255));
                EloamDll.EloamVideo_EnableDeskew(m_hVideo, 0, 0);  //自动裁边
            }
        }

        private void StopCapturer()
        {
            //_bExit = true;
            CloseVideo();
            SetPictureBoxEmpty();
            //ReleaseDeviceControl();
        }

        private void SetPictureBoxEmpty()
        {
            pbxLiveView?.Invoke(new Action(() =>
            {
                //pbxLiveView.Image = null;
                pbxSFZZM.BackgroundImage = null;
                pbxSFZBM.BackgroundImage = null;
                pbxHKBHZY.BackgroundImage = null;
                pbxHKBBRY.BackgroundImage = null;
                pbxHKBBGY.BackgroundImage = null;
                pbxQTZJ.BackgroundImage = null;
                //btnTakePhoto.Invalidate();
            }));
        }

        private void UpdatePictureBackground(PictureBox pbx, string path)
        {
            pbx.Invoke(new Action(() =>
            {
                if (File.Exists(path))
                {
                    System.IO.FileStream fs = new System.IO.FileStream(path, FileMode.Open, FileAccess.Read);
                    pbx.BackgroundImage = System.Drawing.Image.FromStream(fs);
                    fs.Close();
                }
                else
                {
                    pbx.BackgroundImage = null;
                }
            })
            );
        }

        /// <summary>
        /// 清理窗体数据(窗体本次做完后)
        /// </summary>
        public override void ClearData()
        {
            StopWork();
            _appInfo = null;
        }

        private void btnTakePhoto_Click(object sender, EventArgs e)
        {
            try
            {
                //inParam["PhotoDirectory"] = PersonalDirectory;
                //inParam["PhotoIndex"] = _appInfo?.SFZH;
                Button btn = (Button)sender;
                string type = btn.Tag?.ToString();
                if (null != btn && !string.IsNullOrEmpty(type))
                {
                    Log.WriteAsync($"用户点击了拍照:{type}");
                    btn.Enabled = false;
                    HELOAMIMAGE hImg = EloamDll.EloamVideo_CreateImage(m_hVideo, 0, m_hView);

                    if (IntPtr.Zero != hImg)
                    {
                        string filename = $"{PersonalDirectory}\\{type}_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.jpg";
                        PictureBox pictureBox = GetControl<PictureBox>($"pbx{type}") as PictureBox;

                        if (1 == EloamDll.EloamImage_Save(hImg, filename, 0))
                        {
                            Log.WriteAsync($"照片保存成功:{type}-{filename}");
                            EloamDll.EloamView_PlayCaptureEffect(m_hView);
                            if (pictureBox != null)
                            {
                                UpdatePictureBackground(pictureBox, filename);
                                if (null != _appInfo)
                                {
                                    _appInfo.GetType().GetProperty(type).SetValue(_appInfo, filename);
                                }
                                else
                                {
                                    Log.WriteAsync($"_appInfo对象中不存在类型:{type}");
                                }
                                if (_allPicPath.ContainsKey(type))
                                {
                                    if (File.Exists(_allPicPath[type]))   //先把老的文件删除了
                                        File.Delete(_allPicPath[type]);
                                    _allPicPath[type] = filename;
                                }
                                else
                                {
                                    _allPicPath.Add(type, filename);
                                }
                            }
                            else
                            {
                                Log.WriteAsync($"控件:pbx{type}不存在");
                            }
                        }
                        else
                        {
                            Log.WriteAsync($"照片保存失败:{type}-{filename}");
                        }
                        EloamDll.EloamImage_Release(hImg);
                    }
                    btn.Enabled = true;
                }

            }
            catch (Exception ex)
            {
                Log.WriteAsync(ex.Message);
                Log.WriteException(ex.ToString());
            }
        }

        /// <summary>
        /// 清空按钮的点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClear_Click(object sender, EventArgs e)
        {
            try
            {
                _allPicPath.Clear();
                SetPictureBoxEmpty();
                if (_appInfo != null)
                {
                    _appInfo.SFZZM = "";
                    _appInfo.SFZBM = "";
                    _appInfo.HKBHZY = "";
                    _appInfo.HKBBRY = "";
                    _appInfo.HKBBGY = "";
                    _appInfo.QTZJ = "";
                }
            }
            catch (Exception ex)
            {
                Log.WriteAsync(ex.Message);
                Log.WriteException(ex.ToString());
            }
        }

        private void MakePdf()
        {
            try
            {
                if (_allPicPath.Count == 0)
                {
                    //没有高拍
                    return;
                }
                foreach (var item in _allPicPath)
                {
                    if (1 != EloamDll.EloamGlobal_AddFile(item.Value))
                    {
                        Log.WriteAsync($"添加照片{item.Value}失败");
                        return;
                    }
                }
                string filename = $"{PersonalDirectory}\\{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.pdf";
                if (1 != EloamDll.EloamGlobal_CreatePDF(filename))
                {
                    Log.WriteAsync($"创建高拍pdf失败");
                    return;
                }

                if (_appInfo != null)
                    _appInfo.HightCapturePdf = filename;
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
            }
        }

        public override void UpdateData()
        {
            //生成PDF文档
            MakePdf();
            
            _sfzInfo.SFZBM = _appInfo.SFZBM;
            _sfzInfo.SFZZM = _appInfo.SFZZM;
            
            Process.SetValue("SFZInfo", _sfzInfo);
            Process.SetValue("PreApplyInfo", _appInfo);
        }

        protected override void btnNext_Click(object sender, EventArgs e)
        {
            Log.WriteAsync($"apply info:{JsonHandler.ConvertToJsonString(_appInfo)}");
            if (_appInfo != null)
            {
                if (string.IsNullOrEmpty(_appInfo.SFZBM) || !File.Exists(_appInfo.SFZBM))
                {
                    MessageBox.Show("请先进行证件高拍");
                    return;
                }
            }

            UpdateData();
            //StopCountdown();
            if (IsMainPage)
                StopCapturer();
            //OnConfirming();

            int age = IDCardCheck.GetAge(_appInfo.CSRQ);
            if (age < 0)
            {
                Log.WriteAsync($"计算年龄失败：{_appInfo.CSRQ}");
            }
            if (HZChecked && _config.WorkFlow.Signature && (age < 0 || age >= 7))  //7岁后才需要签名
            {
                Process.ToAny("YSLPages.PageSignature");
            }
            else if (_config.WorkFlow.CapFinger)
            {
                Process.ToAny("YSLPages.PageCaptureFinger");
            }
            else if (_config.WorkFlow.ReceiveWay)
            {
                Process.ToAny("YSLPages.PageSelectReceiveWay");
            }
            else
            {
                Process.ToAny("YSLPages.PagePreviewChecking");
            }
            //base.btnNext_Click(sender, e);
        }

        protected override void btnCancel_Click(object sender, EventArgs e)
        {
            if (IsMainPage)
                StopCapturer();
            base.btnCancel_Click(sender, e);
        }
    }
}
